/*
 * @file     IPC_Client.c
 * @brief    source file for setting Ipc
 *
 * Change Logs:
 * Date            Author             Version        Notes
 * 2021-12-17      dengzhiqian        V1.0.0         the first version
 */

#include "IPC_Client.h"
#include "flash_rv.h"
#include "g_IpcFormat.h"
#include "gkt_config.h"

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE

static uint8_t ipc_t_buffer[10] = {0};
static uint8_t r_buffer[10] = {0};
static uint8_t r_s_buffer[10] = {0};

G_Message_TypeDef t_message =
{
    .type = 0,
    .opcode = 0,
    .DataLen = 0,
    .pData = ipc_t_buffer,
};

G_Message_TypeDef r_message =
{
	.type = 0,
	.opcode = 0,
	.DataLen = 0,
	.pData = r_buffer,
};
G_Message_TypeDef r_s_message =
{
	.type = 0,
	.opcode = 0,
	.DataLen = 0,
	.pData = r_s_buffer,
};

G_IpcInitTypeDef  IpcParaInit;
extern const G_Client_Func_TyperDef IpcClientCB;

void G_Ipc_RiscvStart(void)
{
    *(volatile int *)(0xe0008) = 0x1000000;
    *(volatile int *)(0xe000c) = RV_STACK_TOP;
    *(volatile int *)(0xe01f0) = (int)flash_rv;
    *(volatile int*)(0xd0100) = 0xa;
    delay_ms(5);
    *(volatile int*)(0xd0100) = 0xa0a;
    delay_ms(5);
}

void G_Ipc_RiscvClose(void)
{
    *(volatile int *)(0xe0008) = 0x1000000;
    *(volatile int *)(0xe000c) = RV_STACK_TOP;
    *(volatile int*)(0xd0100) = 0;
    //*(volatile int *)(0xe01f0) = (int)0;
}

void G_Ipc_M0_To_Rv_IrqEnable(void)
{
    IPC_M0_RV_IRQ |= (1 << 0);
}

void G_Ipc_M0_To_Rv_IrqDisable(void)
{
    IPC_M0_RV_IRQ &= ~(1 << 0);
}

void G_Rv_To_M0_ClearITPendingBit(void)
{
    IPC_M0_RV_IRQ &= ~(1 << 8);
    IPC_M0_RV_IRQ |= (1 << 8);
}

void G_Ipc_M0_To_Rv_IrqTrig(void)
{
    IPC_M0_RV_IRQ |= (1 << 16);
    delay_us(5);
    IPC_M0_RV_IRQ &= ~(1 << 16);
}

G_IpcStatusTypeDef  G_Ipc_Client_Cmd_Analysing(G_Message_TypeDef *r_message)
{
    t_message.opcode = r_message->opcode;
    t_message.type = r_message->type;
    t_message.DataLen = 0;
    if(IPC_SUCCESS != IpcClientCB[r_message->type][r_message->opcode](r_message->pData))
    {
        return IPC_ERROR_RECV;
    }
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef  G_Ipc_Client_Cmd_Return(G_Message_TypeDef *r_message)
{
    return IPC_SUCCESS;
}


G_IpcStatusTypeDef  G_Ipc_Client_Cmd_Process(void)
{
    if(G_IPC_RV_Recv_Msg(RV2M0,&r_message,0))
    {
        if(IPC_SUCCESS == G_Ipc_Client_Cmd_Analysing(&r_message))
        {
            G_Ipc_Client_Cmd_Return(&r_message);
        }
    }
    if(G_IPC_RV_Recv_SyncMsg(RV2M0,&r_s_message,0))
    {
        if(IPC_SUCCESS == G_Ipc_Client_Cmd_Analysing(&r_s_message))
        {
            G_Ipc_Client_Cmd_Return(&r_s_message);
        }
    }
    return IPC_SUCCESS;
}

#endif
